package com.zrrd.straw1.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zrrd.straw1.entity.*;
import com.zrrd.straw1.mapper.QuestionMapper;
import com.zrrd.straw1.mapper.QuestionTagMapper;
import com.zrrd.straw1.mapper.UserMapper;
import com.zrrd.straw1.mapper.UserQuestionMapper;
import com.zrrd.straw1.service.IQuestionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zrrd.straw1.service.ITagService;
import com.zrrd.straw1.service.IUserService;
import com.zrrd.straw1.vo.QuestionVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zrrd
 * @since 2024-03-03
 */
@Service
public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> implements IQuestionService {

    @Autowired
    UserMapper userMapper ;
    @Autowired
    QuestionMapper questionMapper;
    @Autowired
    IUserService userService;  //找当前登录用户以及找老师用的
    @Autowired
    QuestionTagMapper questionTagMapper;
    @Autowired
    UserQuestionMapper userQuestionMapper;


    @Override
    public Question getQuestionById(Integer id) {
        Question question = questionMapper.selectById( id );
        //补充标签列表
        List<Tag> tags = this.getTagsByNames( question.getTagIds() );
        question.setTags( tags );
        return question;
    }

    @Override
    public PageInfo<Question> getQuestionsByTeacherName(String username, Integer pageNum, Integer pageSize) {

        if(pageNum == null ) pageNum = 1 ;
        if(pageSize == null ) pageSize = 5 ;
        User user = userMapper.findUserByUsername( username );
        //1.静态方法，2.紧邻的查询会做分页查询 3.需要两个分页参数，顺序别写错。
        PageHelper.startPage(pageNum,pageSize);
        List<Question> questions = questionMapper.findTeacherQuestions(user.getId());
        //2.把每个问题的关联标签对象加到每个 Qeustion 中
        for( Question question : questions ){
            // tagIds 是 “Java 基础，Java OO, Web" ->
            List<Tag> tags = this.getTagsByNames( question.getTagIds() ) ;
            question.setTags( tags );  //tag 除了名字，将来还有链接地址，给前端链接绑定用的
        }
        return new PageInfo<Question>( questions );
    }

    @Override
    public Integer countQuestionsByUserId(Integer userId) {
        QueryWrapper<Question> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id",userId);
        //select count(*) from question where user_id = #{userId}
        Integer count = questionMapper.selectCount(queryWrapper);
        return count;
    }

    /**
     * 保存问题，同时建立问题和标签，问题和学生，问题和老师之间的关系
     * @param questionVo
     * @param name
     */
    @Override
    public void saveQuestion(QuestionVo questionVo, String name)  {
        //根据名字获取当前登录用户
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username",name);
        User user = userMapper.selectOne(queryWrapper);

        //把tag名数组，拼接成一个字符串，保存到Questions 表中
        StringBuilder stringBuilder = new StringBuilder();
        for( String tagName : questionVo.getTagNames()){
            stringBuilder.append(tagName).append(",");
        }
        //删除最后一个英文逗号
        String tagIds = stringBuilder.deleteCharAt(stringBuilder.length()-1).toString();

        Question question = new Question()
                .setTitle(questionVo.getTitle())
                .setContent(questionVo.getContent())
                .setUserId(user.getId())
                .setUserNickName(user.getNickName())
                .setStatus(0)  //0-未解决  1-已回答  2-已解决（接受回答）
                .setHits(0)
                .setTagIds(tagIds)
                .setGmtCreate(LocalDateTime.now() );

        //让mapper完成添加问题
        //Mybatis-Plus 简写：MP，
        //添加question对象成功时，会接收数据库生成的ID值，写回到question对象中
        //没有insert,数据表中没有生ID，question对象中就没有ID。
        int num = questionMapper.insert( question );
        if(num!=1){
            throw ServiceException.busy();
        }

        //在添加问题时，需要同时保存问题标签，问题老师之间关系
        //1.根据名字拿到 Tag -> tagId -> questionId -> question_tag数据表
        Map<String,Tag> map = tagService.getName2TagMap();
        for( String tagName : questionVo.getTagNames()){
            //拿到用户选择的标签id.
            int tagId = map.get(tagName).getId();
            //MP 根据question_tag 表定义的实体类
            QuestionTag questionTag = new QuestionTag()
                    .setTagId( tagId )
                    .setQuestionId( question.getId() );
            int num1 = questionTagMapper.insert( questionTag );
            if( num1 != 1){ throw ServiceException.busy(); }
            System.out.println("新增了问题标签关系" + questionTag );
        }

        Map<String,User> masterMap = userService.getMasterMap();
        for(String nickName : questionVo.getTeacherNickNames()){
            User teacher = masterMap.get(nickName);
            UserQuestion userQuestion = new UserQuestion()
                    .setUserId( teacher.getId() )
                    .setQuestionId( question.getId() )
                    .setGmtCreate( LocalDateTime.now() );
            //添加到数据库中
            int num2 = userQuestionMapper.insert( userQuestion );
            if( num2 != 1 ) { throw ServiceException.busy();}
            System.out.println("新增老师问题关系：" + userQuestion );

        }

    }

    @Override
    public PageInfo<Question> getQuestions(String username,Integer pageNum, Integer pageSize ) {
        //业务需求：查询的所有问题查询条件是一个用户的。可以使用 Question 中的userId.
        //开发时，根据用户名查询出用户的信息,目标是 -> userId
        QueryWrapper<User> userQW = new QueryWrapper<>();
        userQW.eq("username", username ); //WHERE username = #{username} ;
        User user = userMapper.selectOne( userQW ) ; // select * from user

        //select * from question where user_id = #{user.id}
        QueryWrapper<Question> qw = new QueryWrapper<>();
        qw.eq("user_id" , user.getId() );
        //问题可以根据状态进行查询
        //问题列表排序问题：最近的问题在最上面，以前依次向下排序。

        /**
         * PageHelper 如何使用，关键一句话： PageHelper.startPage( pageNum, pageSize ) ;
         * 后面紧邻的查询语句就会按照指定参数来查询。
         * 本质就是在后面的查询语句加上 limit 关键字。
         */
        PageHelper.startPage( pageNum, pageSize ) ;
        List<Question> list = questionMapper.selectList( qw );
        //对获取的问题，加进所有关联的标签
        for( Question question : list){
            // trim() 字符串API，用来去除字符串前后空格。
            String names = question.getTagIds().trim();
            List<Tag> tags = getTagsByNames( names );
            question.setTags( tags );
        }

        // 把 list 结果封装到 PageInfo 实例当中，PageInfo 还包含有分页相关的其它信息，提供前端直接获取使用。
        return  new PageInfo<Question>( list ) ;
    }

    @Autowired
    ITagService  tagService;
    /**
     * 根据当前问题的tag_names 属性值转换为List<Tag>集合
     * 每个问题当中， 通过标签名，获取标签集合
     * @param names 数据表 question 中的 tag_names
     * @return  一个问题中所有关联的标签
     */
    public List<Tag> getTagsByNames( String names ){
        String[] tagNames = names.split(",");
        Map<String,Tag> maps = tagService.getName2TagMap();
        List<Tag> tags = new ArrayList<>();
        for( String name : tagNames){
            Tag tag = maps.get( name.trim() );
            tags.add( tag );
        }
        return tags ;
    }

}
